#include "optimize.h"
bool active_done=false;

bool active_merge(MAP x,MAP y){
    bool ret=false;
    FOR_MAP(iter,y){
        int key=MAP_KEY(iter);
        void ** temp=map_insert(x,key);
        if(!*temp) ret=true;
        *temp=(void *)1;
    }
    return ret;
}

static void deal_operand(Operand x, MAP self, bool flag){
    uLL no=x.var.no;
    if(x.var.addr_status==CONSTANT_ID||x.var.addr_status<0) return;
    if(var_mark[x.var.no]) return;
    if(flag&&x.var.addr_status==0) map_erase(self,no);
    else set_insert(self,no);
}

void active_statement(MAP self,operation * o){
    int op=o->op;
    Operand x=o->x,y=o->y,z=o->z;
    if(op>=OP_CALL&&op<=OP_DIV) deal_operand(x,self,true);
    if((op>=OP_ASSIGN&&op<=OP_DIV)||op==OP_IF) deal_operand(y,self,false);
    if(op>=OP_ADD&&op<=OP_DIV) deal_operand(z,self,false);
    if(op>=OP_RET&&op<=OP_IF) deal_operand(x,self,false);
    return;
}

bool active_optimize(MAP self, operation * o){
    int op=o->op;
    if(op>=OP_ASSIGN&&op<=OP_DIV){
        Operand x=o->x;
        if(x.var.addr_status==0&&!set_find(self,x.var.no)&&!var_mark[x.var.no]) {
            active_done=true;
            return false;
        }
    }
    return true;
}

bool active_opt2state(MAP self, operation * now,operation * prev){
    int op1=now->op,op2=prev->op;
    if(op1!=OP_ASSIGN||op2<OP_CALL||op2>OP_DIV) return true;
    Operand term=now->x,temp=now->y,xx=prev->x;
    if(temp.var.no==xx.var.no&&temp.var.addr_status==xx.var.addr_status&&temp.var.addr_status==0){
        int no=temp.var.no;
        if(var_mark[no]) return true;
        if((term.var.addr_status!=0&&(op2!=OP_ASSIGN||(prev->y.var.addr_status!=0&&prev->y.var.addr_status!=CONSTANT_ID)))) return true;
        if(set_find(self,no)) return true;
        prev->x=term;
        return false;
    }
    return true;
}

MAP active_boundary_init(){
    return new_map();
}
